#include <gtest/gtest.h>

#include <QUuid>

#include <Type/User.h>
#include <Store/UserTable.h>

#include <PredefinedConstance/User.h>
#include "CRUDTest.h"
#include "Database.h"

using namespace std;

namespace Store
{
	class User
	{
	public:
		User()
		{
			Database();
		}
        ~User()
        {
            try
            {
                auto idres = TableType::id(testVals.val2insert.phone, testVals.val2insert.passwordHash);
                if (get<bool>(idres))
                {
                    insertedVal.id = get<quint64>(idres);
                    remove();
                }
                idres = TableType::id(testVals.val2update.phone, testVals.val2update.passwordHash);
                if (get<bool>(idres))
                {
                    insertedVal.id = get<quint64>(idres);
                    remove();
                }
            }
            catch (...)
            {
            }
        }
	public:
		typedef TCServer::Type::User DataType;
		typedef TCServer::Store::UserTable TableType;
	public:
		quint64 insert()
		{
            insertedVal = testVals.val2insert;
			auto id = TableType::insert(testVals.val2insert);
            testVals.val2update.id = insertedVal.id = id;
            return id;
		}

		typedef DataType QueryResult;
		QueryResult query()
		{
			auto idres = TableType::id(insertedVal.phone, insertedVal.passwordHash);
            if (!get<bool>(idres))
                throw std::runtime_error("test error : " __FILE__ "Store::User::query()");
            return TableType::query(get<quint64>(idres));
		}

		typedef void UpdateResult;
		void update()
		{
            insertedVal = testVals.val2update;
			return TableType::update(insertedVal);
		}

		typedef void RemoveResult;
		void remove()
		{
            return TableType::remove(insertedVal.id);
		}

	public:
		bool checkInsert(const QueryResult &result)
		{
            return insertedVal.id == result.id
                && insertedVal.phone == result.phone
                && insertedVal.email == result.email
                && insertedVal.username == result.username
                && insertedVal.passwordHash == result.passwordHash;
		}
	private:
		PredefinedConstance::User testVals;
        DataType insertedVal;
	};
}

INSTANTIATE_TYPED_TEST_CASE_P(Store_User, CRUDTest, Store::User);